//
//  WorldWindow.cpp
//  Editor
//
//  Created by Jeppe Nielsen on 11/5/14.
//  Copyright (c) 2014 Jeppe Nielsen. All rights reserved.
//

#include "WorldWindow.hpp"
#include "Project.hpp"
#include "GameObjectModel.hpp"
#include "GameObjectItemDelegate.hpp"
#include "SerializedProperty.hpp"
#include "PropertyEditors.hpp"

std::string WorldWindow::GetName() {
    return "World";
}

void WorldWindow::OnCreate() {

    context->CurrentProject.Changed += event_handler(this, &WorldWindow::ProjectChanged);
    
    CreateContextMenu();
    CreatePropertyEditors();

    QSplitter* splitter = new QSplitter(Qt::Horizontal);
    
    {
    treeView = new QTreeView(window);
    treeView->setModel(&model);
    
    treeView->setSelectionMode(QAbstractItemView::SingleSelection);
    treeView->setSelectionModel(new QItemSelectionModel(&model));

    treeView->setDragEnabled(true);
    
    treeView->viewport()->setAcceptDrops(true);
    treeView->setDropIndicatorShown(true);
    
    treeView->setDragDropMode(QAbstractItemView::InternalMove);
    
    connect(treeView, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(onCustomContextMenu(const QPoint &)));
    
    connect(treeView->selectionModel(), SIGNAL(currentChanged(const QModelIndex &, const QModelIndex &)), this, SLOT(SelectionChanged(const QModelIndex &, const QModelIndex &)));

    
    
    splitter->addWidget(treeView);
    }
    
    {
    
        currentGameObject = 0;
    
        GameObjectItemDelegate* gameObjectItemDelegate = new GameObjectItemDelegate();
        
        connect(
        gameObjectItemDelegate,
        SIGNAL(closeEditor(QWidget*, QAbstractItemDelegate::EndEditHint)),
        this,
        SLOT(propertyDataChanged(QWidget*, QAbstractItemDelegate::EndEditHint))
        );
        
        propertyView = new QTreeView(window);
        propertyView->setSelectionMode(QAbstractItemView::SingleSelection);
        propertyView->setItemDelegate(gameObjectItemDelegate);
        
        splitter->addWidget(propertyView);
    }

    window->setWidget(splitter);

    
    
}

void WorldWindow::ProjectChanged(Property<Context*, Project*>::EventData d) {
    if (!d.Current) return;
    model.SetWorld(&d.Current->world);
}


void WorldWindow::CreateContextMenu() {
    contextMenu = new QMenu(treeView);
    menuRename = new QAction(QString("Rename"), treeView);
    contextMenu->addAction(menuRename);
    
    menuDelete = new QAction(QString("Delete"), treeView);
    contextMenu->addAction(menuDelete);
}

void WorldWindow::SelectionChanged(const QModelIndex &current, const QModelIndex &previous) {
    GameObject* gameObject = static_cast<GameObject*>(current.internalPointer());
    InspectGameObject(gameObject);
}

void WorldWindow::InspectGameObject(GameObject *gameObject) {
    if (currentGameObject) {
        propertyView->setModel(0);
        delete currentGameObject;
    }
    if (gameObject) {
        currentGameObject = new GameObjectModel(gameObject);
        propertyView->setModel(currentGameObject);
        propertyView->expandAll();
        propertyView->resizeColumnToContents(0);
    }
}

void WorldWindow::onCustomContextMenu(const QPoint &point) {
    QModelIndex index = treeView->indexAt(point);
    if (index.isValid()) {
    
        QAction* action = contextMenu->exec(treeView->mapToGlobal(point + QPoint(0,20)));
        
        if (action == menuRename) {
            treeView->edit(index);
        }
        
    }
}

void WorldWindow::propertyDataChanged(QWidget *editor, QAbstractItemDelegate::EndEditHint hint) {
    if (!currentGameObject) return;
    currentGameObject->Deserialize();
}


void WorldWindow::CreatePropertyEditors() {
    SerializedProperty<std::string>::Editor = new PropertyEditorString();
    SerializedProperty<float>::Editor = new PropertyEditorFloat();
    SerializedProperty<int32_t>::Editor = new PropertyEditorInt();
}



